package com.archtecture.control.exceptions;

import com.archtecture.control.enums.Mensagem;
import com.archtecture.control.enums.Severidade;

public class MensagemException extends Exception {

	/**
	 * 
	 */
	private static final long	serialVersionUID	= 8497040468805363538L;

	private Severidade			severidade;

	private Mensagem			mensagem;

	private String[]			parametros;

	/**
	 * Usado apenas pela classe {@link UtilExceptionDiscovery}
	 */
	protected MensagemException() {}

	public MensagemException(Severidade severidade, Mensagem mensagem, String... parametros) {

		this.severidade = severidade;
		this.mensagem = mensagem;
		this.parametros = parametros;

	}

	public MensagemException(Throwable exception) {
		MensagemException mensagem = UtilExceptionDiscovery.discovery(exception);
		parametros = mensagem.getParametros();
		severidade = mensagem.getSeveridade();
		this.mensagem = mensagem.getMensagem();
	}

	public Mensagem getMensagem() {
		return mensagem;
	}

	public String[] getParametros() {
		if (parametros == null) {
			parametros = new String[1];
		}
		return parametros;
	}

	public Severidade getSeveridade() {
		return severidade;
	}

	/**
	 * Usado apenas pela classe {@link UtilExceptionDiscovery}
	 */
	protected void setMensagem(Mensagem mensagem) {
		this.mensagem = mensagem;
	}

	/**
	 * Usado apenas pela classe {@link UtilExceptionDiscovery}
	 */
	protected void setParametros(String[] parametros) {
		this.parametros = parametros;
	}

	/**
	 * Usado apenas pela classe {@link UtilExceptionDiscovery}
	 */
	protected void setSeveridade(Severidade severidade) {
		this.severidade = severidade;
	}

}

class UtilExceptionDiscovery {

	protected static MensagemException discovery(Throwable exception) {

		MensagemException mensagem = new MensagemException();

		// ConstraintViolationException
		verificarConstraintViolationException(exception, mensagem);

		if (mensagem.getMensagem() == null) {
			mensagem.getParametros()[0] = exception.getMessage();
			mensagem.setSeveridade(Severidade.FATAL);
		}

		return mensagem;
	}

	// org.hibernate.exception.ConstraintViolationException: Duplicate entry 'App01' for key 'UNIQUE_SIGLA_APLICACAO'
	private static void verificarConstraintViolationException(Throwable exception, MensagemException mensagem) {
		String stringException = exception.getMessage();

		if (stringException.startsWith("org.hibernate.exception.ConstraintViolationException:") && stringException.contains("Duplicate entry")
				&& stringException.contains("for key")) {

			String param = String.valueOf(stringException.substring(stringException.lastIndexOf("for key") + String.valueOf("for key").length())
					.replace("'", "").trim().toLowerCase());

			mensagem.setMensagem(Mensagem.EXCPT_CONSTRAINT_VIOLATION_EXCEPTION);
			mensagem.getParametros()[0] = param;
			mensagem.setSeveridade(Severidade.FATAL);

		}
	}
}
